package com.doitdroid;

import java.util.ArrayList;
import java.util.Date;

import android.app.TabActivity;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.TabHost;
import android.widget.TabHost.TabSpec;
import android.gesture.Gesture;
import android.gesture.GestureLibrary;
import android.gesture.GestureOverlayView;
import android.gesture.Prediction;
import android.gesture.GestureOverlayView.OnGesturePerformedListener;

public class TaskEditor extends TabActivity implements
		OnGesturePerformedListener {

	private static final String[] PROJECTION = new String[] {
			TaskInfo.Task._ID, TaskInfo.Task.NAME, TaskInfo.Task.DUE_DATE,
			TaskInfo.Task.LIST_ID };
	private static final String TAG = "Task";
	private static final int COLUMN_INDEX_TASK_NAME = 1;
	private static final int COLUMN_INDEX_TASK_DUE_DATE = 2;
	private final int MENU_SAVE = 1, MENU_CANCEL = 2, MENU_DELETE = 3;
	private static final int STATE_EDIT = 0;
	private static final int STATE_INSERT = 1;
	private static final int GROUP_DEFAULT = 0;
	private int currentState;
	private String originalName;
	private Date originalDueDate;
	private Uri currentUri;
	private Cursor data;
	private EditText taskNameEditor;
	private DatePicker taskDueEditor;
	private GestureLibrary gestureLibrary;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		if (!this.setupAction()) {
			this.finish();
			return;
		}

		this.setupLayout();

		this.initializeFields();
		this.getData();
	}

	private void setupLayout() {
		this.setContentView(R.layout.taskeditor);

		TabHost tabs = getTabHost();
		tabs.setup();

		TabSpec tspec1 = tabs.newTabSpec("First tab");
		tspec1.setIndicator(getString(R.string.taskEditorBasicTabText));
		tspec1.setContent(R.id.taskEditorBasicTabLayout);
		tabs.addTab(tspec1);

		TabSpec tspec2 = tabs.newTabSpec("Sec tab");
		tspec2.setIndicator(getString(R.string.taskEditorAlarmsTabText));
		tspec2.setContent(R.id.taskEditorSecondTabLayout);
		tabs.addTab(tspec2);
	}

	@Override
	protected void onResume() {
		super.onResume();

		// If we didn't have any trouble retrieving the data, it is now
		// time to get at the stuff.
		if (data != null) {
			// Make sure we are at the one and only row in the cursor.
			data.moveToFirst();

			// This is a little tricky: we may be resumed after previously being
			// paused/stopped. We want to put the new text in the text view,
			// but leave the user where they were (retain the cursor position
			// etc). This version of setText does that for us.
			String taskName = data.getString(COLUMN_INDEX_TASK_NAME);
			taskNameEditor.setTextKeepState(taskName);

			long taskDueDate = data.getInt(COLUMN_INDEX_TASK_DUE_DATE);
			if (originalName == null)
				originalName = taskName;

			if (taskDueDate > 0) {
				Date date = new Date(taskDueDate);
				taskDueEditor.updateDate(date.getYear(), date.getMonth(),
						date.getDay());
				if (originalDueDate == null)
					originalDueDate = date;
			}

		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		menu.add(GROUP_DEFAULT, MENU_SAVE, 0, "Save");
		menu.add(GROUP_DEFAULT, MENU_CANCEL, 0, "Cancel");
		menu.add(GROUP_DEFAULT, MENU_DELETE, 0, "Delete");
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case MENU_SAVE:
			this.SaveListItem();
			return true;
		case MENU_CANCEL:
			this.CancelListItemEdition();
			return true;
		case MENU_DELETE:
			this.DeleteListItem();
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
		ArrayList<Prediction> predictions = gestureLibrary.recognize(gesture);

		if (!predictions.isEmpty()
				&& predictions.get(0).name.equalsIgnoreCase("Delete")
				&& predictions.get(0).score > 5) {
			this.DeleteListItem();
		}

	}

	private void DeleteListItem() {
		if (data != null) {
			data.close();
			data = null;
			getContentResolver().delete(currentUri, null, null);
		}

		setResult(RESULT_OK);
		finish();
	}

	private void CancelListItemEdition() {
		if (data != null) {
			if (currentState == STATE_EDIT) {
				// Put the original note text back into the database
				data.close();
				data = null;

			} else if (currentState == STATE_INSERT) {
				// We inserted an empty note, make sure to delete it
				DeleteListItem();
			}
		}
		setResult(RESULT_CANCELED);
		finish();
	}

	private void SaveListItem() {
		data.close();
		data = null;
		ContentValues values = new ContentValues();

		values.put(TaskInfo.Task.NAME, taskNameEditor.getText().toString());

		getContentResolver().update(currentUri, values, null, null);

		setResult(RESULT_OK);
		finish();
	}

	private void initializeFields() {
		taskNameEditor = (EditText) findViewById(R.id.taskEditorNameEditor);
	}

	private void getData() {
		data = managedQuery(currentUri, PROJECTION, null, null, null);
	}

	private boolean setupAction() {
		final Intent intent = getIntent();
		boolean result = true;

		// Do some setup based on the action being performed.
		final String action = intent.getAction();
		if (Intent.ACTION_EDIT.equals(action)) {
			// Requested to edit: set that state, and the data being edited.
			currentState = STATE_EDIT;
			currentUri = intent.getData();
		} else if (Intent.ACTION_INSERT.equals(action)) {
			// Requested to insert: set that state, and create a new entry
			// in the container.
			currentState = STATE_INSERT;
			currentUri = getContentResolver().insert(intent.getData(), null);

			// If we were unable to create a new note, then just finish
			// this activity. A RESULT_CANCELED will be sent back to the
			// original activity if they requested a result.
			if (currentUri == null) {
				Log.e(TAG, "Failed to insert new note into "
						+ getIntent().getData());
				result = false;
			}

			// The new entry was created, so assume all will end well and
			// set the result to be returned.
			setResult(RESULT_OK,
					(new Intent()).setAction(currentUri.toString()));

		} else {
			// Whoops, unknown action! Bail.
			Log.e(TAG, "Unknown action, exiting");
			finish();
			result = false;
		}

		return result;
	}
}
